/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package core;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.junit.*;
import static org.junit.Assert.*;

/**
 *
 * @author Eric
 */
public class ItemTest {
    //variables
    private ProductContainer unit1;
    private ProductContainer unit2;
    
    private Product product1;
    private Product product2;
    
    private Calendar cal1;
    private Calendar cal2;
    private Calendar cal3;
    
    private Item item1;
    private Item item2;
    
    private static int BAR_CODE_LENGTH = 12;
    private static long INITIAL_BAR_CODE = 2000000000;
    private static String BCODE_TWO_NUMS = "42";
    
    ItemManager ib;
    
    
    
    public ItemTest() {
        
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }
    
    @Before
    public void setUp() {
        
        ib = ItemManager.getInstance();
        
        
        
        Calendar c = new GregorianCalendar();
        product1 = new Product(c, new Barcode("12345"), "description",new Amount(Unit.count, 1), 0, 0);
        //newDate.setTime(newDate.getTime() + 100000);
        product1 = new Product(c, new Barcode("123456789012"), "description",new Amount(Unit.count, 1), 0, 0);
        unit1 = new StorageUnit("storage1");
        cal1 = new GregorianCalendar();
        
        product2 = new Product(c, new Barcode("12345"), "description",new Amount(Unit.count, 1), 3, 1);
        cal2 = new GregorianCalendar();
        cal2.add(Calendar.MONTH, 3);
        unit2 = new StorageUnit("storage2");
        cal3 = new GregorianCalendar();
        return;
        
    }
    
    @After
    public void tearDown() {
    }

    @Test
    public void testSetExpirationDate() {
        System.out.println("setExpirationDate");
        
        //1
        item1 = new Item(product1, unit1, cal1,ib.generateBarcode());
        
        Calendar result = item1.getExpirationDate();
        Calendar expected = item1.getEntryDate();
        expected.add(Calendar.MONTH, item1.getProduct().getShelfLife());
        
        //assertTrue(expected.equals(result));
        assertTrue(result == null);
        //assertTrue(expected.get(Calendar.MONTH)==result.get(Calendar.MONTH));
        //assertTrue(expected.get(Calendar.DATE)==result.get(Calendar.DATE));
        //assertTrue(expected.get(Calendar.YEAR)==result.get(Calendar.YEAR));
        
        //2
        item1 = new Item(product2, unit1, cal1,ib.generateBarcode());
        
        result = item1.getExpirationDate();
        expected = item1.getEntryDate();
        expected.add(Calendar.MONTH, item1.getProduct().getShelfLife());
        
        //assertTrue(expected.equals(result));
    }

    @Test
    public void testSetProduct() {
        System.out.println("setProduct");
        //1
        item1 = new Item(product1, unit1, cal1,ib.generateBarcode());
        
        item1.setProduct(product2);
        
        Product expected = item1.getProduct();
        
        assertTrue(expected.equals(product2));
        
        //2
        boolean success = false;
        try{
            item1.setProduct(null);
        }
        catch(IllegalArgumentException e)
        {
            success = true;
        }
        assertTrue(success);
    }

    @Test
    public void testSetAndGetProductContainer() 
    {
        //1 set
        item1 = new Item(product1, unit1, cal1,ib.generateBarcode());
        boolean success = false;
        try{
            item1.setProductContainer(null);
        }
        catch(IllegalArgumentException e)
        {
            success = true;
        }
        assertTrue(success);
        
        //2 set
        item1.setProductContainer(unit2);
        assertTrue(item1.getProductContainer().equals(unit2));
        
        //3 get
        item1 = new Item(product1, unit1, cal1,ib.generateBarcode());
        assertTrue(item1.getProductContainer().equals(unit1));
    }

    @Test
    public void testGetProduct() {
       //1
        item1 = new Item(product1, unit1, cal1,ib.generateBarcode());
        assertTrue(item1.getProduct().equals(product1));
    }

    @Test
    public void testGetExpirationDate() {
        System.out.println("getExpirationDate");
        //1
        item1 = new Item(product2, unit1, cal1, ib.generateBarcode());
        Calendar expResult = new GregorianCalendar();
        expResult.add(Calendar.MONTH, 3);
        Calendar result = item1.getExpirationDate();
        
        // make sure it is within 3 milliseconds
        assertTrue(result.getTimeInMillis()-expResult.getTimeInMillis() < 3);
        
    }

    @Test
    public void testRemoveItem() {
        System.out.println("removeItem");
        //1
        item1 = new Item(product1, unit1, cal1, ib.generateBarcode());
        item1.removeItem();
        
        
        assertTrue(item1.getProductContainer() == null);
        try{
            assertTrue(item1.getExitTime() != null);
            assertTrue(item1.getExitTime().compareTo(new GregorianCalendar())<=0);
            assertTrue(item1.getEntryDate().compareTo(item1.getExitTime())<=0);
        }
        catch(Exception e)
        {
            fail();
        }
        
    }

    @Test
    public void testGetExitTime() throws Exception {
        System.out.println("getExitTime");
        //1
        boolean success = false;
        item1 = new Item(product1, unit1, cal1, ib.generateBarcode());
        try
        {
            item1.getExitTime();
        }
        catch(Exception e)
        {
            assertTrue(success);
        }
        
        //2
        item1 = new Item(product1, unit1, cal1, ib.generateBarcode());
        success = false;
        item1.removeItem();
        
        if(item1.getExitTime() != null)
        {
            success = true;
        }
            
        assertTrue(success);
    }

    @Test
    public void testIsRemoved() {
        System.out.println("isRemoved");
        //1
        item1 = new Item(product1, unit1, cal1, ib.generateBarcode());
        item1.removeItem();
        assertTrue(item1.isRemoved());
    }

    @Test
    public void testGetBarcode() {
        System.out.println("getBarcode");
        //1
        item1 = new Item(product1, unit1, cal1, ib.generateBarcode());
        assertTrue(!item1.getBarcodeString().isEmpty());
        
        //2
        item1 = new Item(product1, unit1, cal1, ib.generateBarcode());
        assertTrue(item1.getBarcodeString().length() == BAR_CODE_LENGTH);
        assertTrue(item1.getBarcodeString().contains(BCODE_TWO_NUMS));
    }

    @Test
    public void testSetAndGetEntryDate() {
        //1
        System.out.println("setAndGetEntryDate");
        item1 = new Item(product1, unit1, cal1, ib.generateBarcode());
        item1.setEntryDate(cal3);
        assertTrue(item1.getEntryDate().equals(cal3));
    }
    
    @Test
    public void testEntryDateConstraints()
    {
    	//--(non-empty) Item 242 
    	//--(not in future)
    	//--(not prior to 1/1/2000).
    	Calendar c1 = new GregorianCalendar();
    	c1.add(Calendar.YEAR, 1);
    	
    	boolean thrown = false;
    	try{
    		Item i1 = new Item(product1, unit1, c1, ib.generateBarcode());
    	}catch (Exception e)
    	{
    		thrown = true;
    	}
    	assertTrue(thrown);
    	
    	thrown = false;
    	try{
    		c1.add(Calendar.YEAR, +30);
    		Item i1 = new Item(product1, unit1, c1, ib.generateBarcode());
    	}catch (Exception e)
    	{
    		thrown = true;
    	}
    	assertTrue(thrown);
    }
}
